﻿function RangeUtil(textBox){
	this.textBox = textBox;
	this.range={start:0,end:0,text:'',bookmark:null};
}

RangeUtil.prototype.replace=function(str) {
	this.replaceText(str);
	this.display();
};

RangeUtil.prototype.debug=function(){
	alert("selected("+this.range.start+","+ this.range.end+") = {" + this.range.text +"}[length:"+this.range.text.length+"]");
};

RangeUtil.prototype.display=function(){ 
	this.textBox.focus(); 
	if( this.textBox.setSelectionRange ){ //W3C
		this.textBox.setSelectionRange(this.range.start,this.range.end); 
	} else if (this.textBox.createTextRange) { //IE
		this.select4IE();
	} 
};

RangeUtil.prototype.select4IE=function() {
	var tr = this.textBox.createTextRange();
	var value = this.textBox.value;
	if(value.length === this.range.start){
		tr.collapse(false); 
		tr.select(); 
		return;
	}
	//tr.moveToBookmark(this.range.bookmark);
	var start = this.range.start;	
	tr.collapse(true); 
    for(var i=0; i<value.length && i<this.range.start; i++){   
      if(this.isLineBreak(value.charAt(i))){ start--; }   
    }   
	tr.moveEnd('character', start+this.range.text.length); //first to end, then to start;
	tr.moveStart('character', start); 
	tr.select(); 
};

RangeUtil.prototype.replace4IE=function(newText) {//not test
	var sr = document.selection.createRange();
	sr.text = newText;
	sr.setEndPoint('StartToEnd', sr);
	sr.select();
};

RangeUtil.prototype.replaceText=function(newText) {
	var prefix = this.textBox.value.substr(0, this.range.start);
	var suffix = this.textBox.value.substr(this.range.end);
	var sTop = this.textBox.scrollTop;
	this.range.text = newText;
	this.range.end = this.range.start + newText.length;
	this.textBox.value = prefix + newText + suffix;
	// Fixbug: After textarea.values = nValue, scrollTop value to 0
	if( sTop && this.textBox.scrollTop !=sTop) {
		this.textBox.scrollTop = sTop;
	}
};

RangeUtil.prototype.saveRangeInfo=function() {
	if (typeof (this.textBox.selectionStart) == "number") {// W3C,Firefox(1.5),ie8+的话，方法很简单
		this.range.start = this.textBox.selectionStart;
		this.range.end = this.textBox.selectionEnd;
		if( this.range.end-this.range.start>0){
			this.range.text = this.textBox.value.substring(this.range.start, this.range.end);
		}else{
			this.range.text='';
		}
	} else if (document.selection) { // IE(6.0)的方法，麻烦得很，还要计算上'/n'
		//not tested, need IE6
		var range_sub = document.selection.createRange();
		this.range.text = range_sub.text;
		this.range.bookmark = range_sub.getBookmark();
		if (range_sub.parentElement() == this.textBox) {
			this.range.start = this.getRangeStart4IE();
			this.range.end = this.getRangeEnd4IE();
			//this.range.end = this.range.start+this.range.text.length;
		};
	}
};

RangeUtil.prototype.getRangeStart4IE=function() {
	var range_sub = document.selection.createRange();
	// create a selection of the whole textarea
	var range_all = document.body.createTextRange();
		range_all.moveToElementText(this.textBox);
	// 两个range，一个是已经选择的text(range_sub)，一个是整个textarea(range_all)
	// range_all.compareEndPoints() 比较两个端点，如果range_all比range更往左(further to the left)，则 返回小于0的值，则range_all往右移一点，直到两个range的start相同。
	// calculate selection start point by moving beginning of range_all to beginning of range_sub
	var start = 0;
	for (; range_all.compareEndPoints("StartToStart", range_sub) < 0; start++){
		range_all.moveStart('character', 1);
	}
	// get number of line breaks from textarea start to selection start and add them to start
	for ( var i = 0; i <= start; i++) {
		if (this.isLineBreak(this.textBox.value.charAt(i))){
			start++;
		};
	}
	return start;
};

RangeUtil.prototype.getRangeEnd4IE=function() {
	var range_sub = document.selection.createRange();
	var range_all = document.body.createTextRange();
		range_all.moveToElementText(this.textBox);
	// calculate selection end point by moving beginning of range_all to end of range
	var end = 0;
	for (; range_all.compareEndPoints('StartToEnd', range_sub) < 0; end++){
		range_all.moveStart('character', 1);
	}
	// get number of line breaks from textarea start to selection end and add them to end
	for ( var i = 0; i <= end; i++) {
		if (this.isLineBreak(this.textBox.value.charAt(i))){
			end++;
		};
	}
	return end;
};

RangeUtil.prototype.isLineBreak=function(chr) {
	return (chr == '\n' );//||(chr == '\r' )
};


RangeUtil.prototype.setPosition=function(start,end){ 
	this.range.start=start;
	this.range.end=end;
	if(end-start>0){
		this.range.text = this.textBox.value.substring(start, end);
	}else{
		this.range.text='';
	}
	this.display();
}; 

RangeUtil.prototype.sync=function(){
	this.saveRangeInfo();
};
